
import (
	"context"
	"fmt"
	"io/ioutil"
	"log"
	"os"
	"strings"
	"time"

	"github.com/chromedp/cdproto/network"
	"github.com/chromedp/chromedp"
)

// type Exec func(*chromedp.ExecAllocator)

type Chrome struct {
	Headless   bool
	ChromePath string
	opts       []func(*chromedp.ExecAllocator)
	ctx        context.Context
}

func (self *Chrome) addOptions() {
	self.opts = append(self.opts[:],
		chromedp.Flag("headless", self.Headless),
		chromedp.ExecPath(self.ChromePath),
	)
}

func (self *Chrome) newContext() {
	allCtx, _ := chromedp.NewExecAllocator(
		context.Background(),
		self.opts...,
	)
	ctx, _ := chromedp.NewContext(allCtx)
	// var cancel context.CancelFunc
	self.ctx, _ = context.WithTimeout(ctx, 30*time.Second)
	// defer cancel()
	// defer chromedp.Cancel(ctx)
}

func NewChromedp() {
	opts := []chromedp.ExecAllocatorOption{
		chromedp.Flag("headless", false),
		chromedp.ExecPath(`D:\Program Files\Chrome\Application\chrome.exe`),
	}
	opts = append(chromedp.DefaultExecAllocatorOptions[:], opts...)
	allocCtx, _ := chromedp.NewExecAllocator(
		context.Background(),
		opts...,
	)
	ctx, _ := chromedp.NewContext(
		allocCtx,
		// 设置日志方法
		chromedp.WithLogf(log.Printf),
	)
	// defer cancel()
	ctx, cancel := context.WithTimeout(ctx, 30*time.Second)
	defer cancel()
	defer chromedp.Cancel(ctx)

	if err := chromedp.Run(ctx, myTask()); err != nil {
		log.Fatal(err)
		return
	}
	time.Sleep(5 * time.Second)

}
func myTask() chromedp.Tasks {
	return chromedp.Tasks{
		// loadCookies(),
		chromedp.Navigate("http://10.195.36.50/#/signin"),
		// checkLoginStatus(),
		chromedp.SendKeys(`#ng-app > div > div:nth-child(1) > div > div > span > div > span > div > div.tb-login.ng-scope > span > form > div.ng-scope > div:nth-child(1) > div > div > input`, "admin"),
		chromedp.SendKeys(`#ng-app > div > div:nth-child(1) > div > div > span > div > span > div > div.tb-login.ng-scope > span > form > div.ng-scope > div.tb-login-text-box.tb-padded.ng-scope > div > div > input`, "admin"),
		chromedp.Click(`#ng-app > div > div:nth-child(1) > div > div > span > div > span > div > div.tb-login.ng-scope > span > form > button`, chromedp.BySearch),
		chromedp.WaitVisible(`#ng-app > div > div:nth-child(1) > div > div > span > div > span > div > div.tb-login-site-picker > span > div > div > div > div:nth-child(1) > div:nth-child(4) > div > div > span`, chromedp.BySearch),
		chromedp.Click(`#ng-app > div > div:nth-child(1) > div > div > span > div > span > div > div.tb-login-site-picker > span > div > div > div > div:nth-child(1) > div:nth-child(4) > div > div > span`, chromedp.BySearch),

		chromedp.WaitVisible(`#ng-app > div > div:nth-child(1) > div > div > div > div > div > div > div > span > section > header > h1`, chromedp.BySearch),
		// chromedp.Click(`#dialog > div.dialog-wrapper > div > div.dialog-footer > div.dialog-footer-ok`),
		// getCode(),
		// saveCookies(),

	}
}

func getCode() chromedp.ActionFunc {
	return func(ctx context.Context) (err error) {
		var code []byte
		// 2. 截图
		// 注意这里需要注明直接使用ID选择器来获取元素（chromedp.ByID）
		if err = chromedp.Screenshot(`#wximport`, &code, chromedp.ByID).Do(ctx); err != nil {
			return
		}

		// 3. 保存文件
		if err = ioutil.WriteFile("code.png", code, 0755); err != nil {
			return
		}
		return

	}
}

func saveCookies() chromedp.ActionFunc {
	return func(ctx context.Context) (err error) {
		// 等待二维码登陆
		if err = chromedp.WaitVisible(`#app`, chromedp.ByID).Do(ctx); err != nil {
			return
		}

		// cookies的获取对应是在devTools的network面板中
		// 1. 获取cookies
		cookies, err := network.GetAllCookies().Do(ctx)
		if err != nil {
			return
		}
		fmt.Println(cookies)
		var ck string
		for _, v := range cookies {
			ck = ck + v.Name + "=" + v.Value + ";"
		}
		println(ck)

		// 2. 序列化
		// cookiesData, err := network.GetAllCookiesReturns{Cookies: cookies}.MarshalJSON()

		// if err != nil {
		// 	return
		// }

		// 3. 存储到临时文件
		if err = ioutil.WriteFile("cookies.tmp", []byte(ck), 0755); err != nil {
			return
		}
		// if err = ioutil.WriteFile("cookies.tmp2", , 0755); err != nil {
		// 	return
		// }
		return
	}
}

func loadCookies() chromedp.ActionFunc {
	return func(ctx context.Context) (err error) {
		// 如果cookies临时文件不存在则直接跳过
		if _, _err := os.Stat("cookies.tmp"); os.IsNotExist(_err) {
			return
		}

		// 如果存在则读取cookies的数据
		cookiesData, err := ioutil.ReadFile("cookies.tmp")
		if err != nil {
			return
		}

		// 反序列化
		cookiesParams := network.SetCookiesParams{}
		fmt.Println(string(cookiesData))
		fmt.Println(cookiesParams.UnmarshalJSON(cookiesData))
		if err = cookiesParams.UnmarshalJSON(cookiesData); err != nil {
			return
		}

		// 设置cookies
		// network.SetExtraHTTPHeaders()
		return network.SetCookies(cookiesParams.Cookies).Do(ctx)
	}
}

func checkLoginStatus() chromedp.ActionFunc {
	return func(ctx context.Context) (err error) {
		var url string
		if err = chromedp.Evaluate(`window.location.href`, &url).Do(ctx); err != nil {
			return
		}
		if strings.Contains(url, "https://account.wps.cn/usercenter/apps") {
			log.Println("已经使用cookies登陆")
			chromedp.Stop()
		}
		return
	}
}
func main(){
    chromedp.NewChromedp()
}